<template>
  <div
    class="cover"
    ref="coverRef"
    :style="{
      'border-radius': borderRadius,
      width: width ? width + 'px' : '100%',
      height: width ? width * scale + 'px' : '100%'
    }"
  >
    <el-image
      :lazy="lazy"
      :src="fileSource || fileImage"
      :fit="fit"
      v-if="fileSource || fileImage"
      @click="showPreviewHandler"
    >
      <template #placeholder>
        <div class="loading" :style="{ height: loadingHeight + 'px' }">
          <img :src="getLocalImage('playing.gif')" alt="" />
        </div>
      </template>
      <template #error>
        <img
          class="el-image__inner"
          :style="{ 'object-fit': fit }"
          :src="getLocalImage('404_cover.png')"
          alt=""
        />
      </template>
    </el-image>
    <div v-else class="no-image">请选择图片</div>
    <el-image-viewer
      :hide-on-click-modal="true"
      v-if="showPreview"
      :teleported="true"
      :url-list="imageList"
      :initial-index="0"
      @close="showPreview = false"
    />
  </div>
</template>

<script setup lang="ts">
import { computed, onMounted, ref, watch, withDefaults } from 'vue'
import { getLocalImage } from '@/utils/utilsFun.ts'
import { useHomeStore } from '@/stores/home'

const homeStore = useHomeStore()
const props = withDefaults(
  defineProps<{
    source: string | File
    width?: number
    fit?: 'fill' | 'contain' | 'cover' | 'none' | 'scale-down'
    preview?: boolean
    img404?: string
    borderRadius?: string
    lazy?: boolean
    scale?: number
    defautlImg?: string
  }>(),
  {
    //提供默认值
    fit: 'scale-down',
    preview: false,
    img404: '404_cover.png',
    borderRadius: '5px',
    lazy: true,
    scale: 0.6
  }
)

const fileImage = ref<string | undefined>() // 存储文件读取结果

// 使用 watch 监听 props.source 变化，处理副作用（文件读取）
watch(
  () => props.source,
  (newSource) => {
    if (newSource instanceof File) {
      //创建文件读取器
      const reader = new FileReader()
      // 开始读取文件
      reader.readAsDataURL(newSource)
      //读取完成后的回调
      reader.onload = ({ target }) => {
        fileImage.value = target?.result as string // 更新响应式数据
      }
    }
  },
  { immediate: true }
)

const fileSource = computed(() => {
  // 无来源且无默认图
  if (!props.source && !props.defautlImg) {
    return null
  }

  // 无来源但有默认图
  if (!props.source && props.defautlImg) {
    return getLocalImage(props.defautlImg) // 假设这是纯函数
  }

  // 字符串类型的资源地址
  if (typeof props.source === 'string') {
    console.log(props.source, ' @@@@@@@@')
    const modifiedUrl = props.source.replace(/(.*?)\.jpg(_thumbnail\.jpg)/, '$1$2')
    return `${homeStore.sourcePath}${modifiedUrl}`
  }

  // File 类型（由 watch 处理，这里只返回缓存结果）
  if (props.source instanceof File) {
    return fileImage.value // 返回 watch 中处理的结果
  }

  // 其他情况
  return null
})

//预览图片
const showPreview = ref(false)
const imageList = computed(() => {
  if (!props.preview) {
    return []
  }
  if (typeof props.source !== 'string') {
    return []
  }
  //把_thumbnail去除掉之后就是返回的原始图(预览的大图)
  const sourceImge = homeStore.sourcePath + props.source.replace('_thumbnail.jpg', '')
  console.log(sourceImge, '预览图片')
  return [sourceImge]
})

const showPreviewHandler = () => {
  if (!props.preview) {
    return
  }
  showPreview.value = true
}

const loadingHeight = ref()
const coverRef = ref()

onMounted(() => {
  loadingHeight.value = coverRef.value.clientWidth * props.scale!
})

function removeMainExtension(url: any) {
  return url.replace(
    /(sourceName=[^&]*?)(\.\w+)(_thumbnail\.jpg)/gi,
    '$1$3' // 保留捕获组1（sourceName=...）和捕获组3（_thumbnail.jpg）
  )
}
</script>

<style lang="less" scoped>
.cover {
  position: relative;
  overflow: hidden;
  cursor: pointer;
  background-color: #f8f8f8;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  :deep(.is-loading) {
    display: none;
  }
  :deep(.el-image) {
    width: 100%;
    height: 100%;
  }
  :deep(.el-image__wrapper) {
    position: relative;
    vertical-align: top;
    width: 100%;
    height: 100%;
    display: flex;
  }
  .icon-image-error {
    margin: 0px auto;
    font-size: 20px;
    color: #838383;
    height: 100%;
  }
  .loading {
    width: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    img {
      width: 20px;
    }
  }
  .no-image {
    text-align: center;
    color: #9f9f9f;
  }
}
</style>
